﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DimensionData.Data2
{
    public class DRow
    {
        public int RowIndex { get; set; }
        public string DPath { get; set; }

        public DItem[] Items { get; set; }

        public string GetCodePath(int? depth = null)
        {
            StringBuilder builder = new StringBuilder();
            if (depth == null)
            {
                for (int index = 0; index < Items.Length; index++)
                {
                    builder.AppendFormat(@"\{0}", Items[index].Code);
                }
            }
            else
            {
                for (int index = 0; index <= depth.Value; index++)
                {
                    builder.AppendFormat(@"\{0}", Items[index].Code);
                }
            }
            return builder.ToString();
        }

        public DRow Connect(DRow row)
        {
            DRow tempRow = new DRow();
            tempRow.RowIndex = 0;
            tempRow.Items = new DItem[this.Items.Length + row.Items.Length];

            for (int index = 0; index < this.Items.Length; index++)
            {
                tempRow.Items[index] = this.Items[index];
            }
            for (int index = 0; index < row.Items.Length; index++)
            {
                tempRow.Items[this.Items.Length + index] = row.Items[index];
            }

            return tempRow;
        }

        /// <summary>
        /// 推算出此路径所使用的公式,
        /// 1.按照此维度没有公式的定义，那么他们就只能继承前一个维度的公式定义
        /// 2.如果此维度存在公式的定义，则使用自己的公式，覆盖掉上级维度的公式
        /// </summary>
        /// <returns></returns>
        public FormulaRef GetFormula()
        {
            for (int index = this.Items.Length - 1; index >= 0; index--)
            {
                DItem item = this.Items[index];
                if (!string.IsNullOrEmpty(item.Formula))
                {
                    FormulaRef fRef = new FormulaRef();
                    fRef.DimIndex = index;
                    fRef.Value = item.Formula;
                    return fRef;
                }
            }
            return null;
        }

        /// <summary>
        /// 从公式规则中获取此行对应的规则
        /// </summary>
        /// <param name="rules"></param>
        /// <returns></returns>
        public FormulaRef GetFormula(List<FormulaRule> rules)
        {
            if (rules == null)
            {
                return null;
            }

            string fullPath = GetCodePath();
            PathExpression pathExpression = new PathExpression(fullPath);

            int maxCompareWeight = -1;
            FormulaRule matchRule = null;
            foreach (var rule in rules)
            {
                PathExpression ruleExp = new PathExpression(rule.TargetExpression);
                int compareResult = pathExpression.Compare(ruleExp);
                if (compareResult > maxCompareWeight)
                {
                    maxCompareWeight = compareResult;
                    matchRule = rule;
                }
            }
            if (matchRule != null)
            {
                return new FormulaRef()
                {
                    Value = matchRule.FormulaExpression
                };
            }
            return null;
        }

        /// <summary>
        /// 获取所匹配到的数据引用规则
        /// </summary>
        /// <param name="rules"></param>
        /// <returns></returns>
        public DataRef GetDataRef(List<DataRefRule> rules)
        {
            if (rules == null)
            {
                return null;
            }

            string fullPath = GetCodePath();
            PathExpression pathExpression = new PathExpression(fullPath);

            int maxCompareWeight = -1;
            DataRefRule matchRule = null;
            foreach (var rule in rules)
            {
                int compareResult = pathExpression.Compare(rule.DestPathExpression);
                if (compareResult > maxCompareWeight)
                {
                    maxCompareWeight = compareResult;
                    matchRule = rule;
                }
            }
            if (matchRule != null)
            {
                return new DataRef()
                {
                    SourceDocCode = matchRule.SourceDocCode,
                    SourceExp = matchRule.SourcePathExpression
                };
            }
            return null;
        }

        //public object GetCellMode(List<FormulaRule> fRules, List<DataRefRule> dRefs)
        //{
        //    return null;
        //}
    }
}
